package com.example.chatgpt.service;

import com.example.chatgpt.model.OpenAIRequest;
import com.example.chatgpt.model.OpenAIResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.concurrent.TimeUnit;

@Service
public class ChatgptService {

    private static final Logger logger = LoggerFactory.getLogger(ChatgptService.class);

    @Value("${openai.api.endpoint}")
    private String openAIEndpoint;

    @Value("${openai.api.key}")
    private String openAIKey;

    @Value("${openai.model}")
    private String openAIModel;

    @Value("${general.proxy.host}")
    private String generalProxyHost;

    @Value("${general.proxy.port}")
    private Integer generalProxyPort;

    private OkHttpClient client;

    @PostConstruct
    public void init() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        // Increase the timeout durations
        builder = builder
                .connectTimeout(60, TimeUnit.SECONDS) // increase connection timeout
                .writeTimeout(60, TimeUnit.SECONDS) // increase write timeout
                .readTimeout(60, TimeUnit.SECONDS); // increase read timeout

        if (generalProxyHost != null && !generalProxyHost.trim().isEmpty() && generalProxyPort != null) {
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(generalProxyHost, generalProxyPort));
            builder = builder.proxy(proxy);
        }

        client = builder.build();
    }

    private final ObjectMapper objectMapper = new ObjectMapper();

    public OpenAIResponse askChatGPT(String question) throws IOException {
        logger.info("Preparing OpenAI request...");
        OpenAIRequest requestPayload = new OpenAIRequest(openAIModel, question);

        String jsonPayload = objectMapper.writeValueAsString(requestPayload);

        RequestBody body = RequestBody.create(jsonPayload, MediaType.get("application/json; charset=utf-8"));

        Request request = new Request.Builder()
                .url(openAIEndpoint)
                .header("Authorization", "Bearer " + openAIKey)
                .post(body)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                logger.error("Error in OpenAI response: {}", response);
                throw new IOException("Unexpected code " + response);
            }

            String responseBody = response.body().string();
            System.out.print(responseBody);
            return objectMapper.readValue(responseBody, OpenAIResponse.class);  // Return OpenAIResponse directly
        } catch (IOException e) {
            logger.error("Exception during OpenAI request", e);
            throw e;  // or handle it as per your requirements
        }
    }

    public CompletableFuture<OpenAIResponse> askChatGPTAsync(String question) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return askChatGPT(question);
            } catch (IOException e) {
                logger.error("Exception during OpenAI request", e);
                throw new RuntimeException(e); // or handle it as per your requirements
            }
        });
    }
}
